; file: 

; asm_io.inc was created by the textbook's authors.  It includes i/o functions
%include "asm_io.inc"

; Initialized output data
segment .data

prompt0 db "What number n of elements would you like to sort? ", 0
prompt1 db "Please give number ", 0
prompt3 db ": ", 0
prompt2 db "Please chose (1) Bubblesort, (2) Quicksort: ", 0
outmsg1 db ",", 0
outmsg2 db "Signed Bubble Sort: ", 0
outmsg3 db "Signed Quick Sort: ", 0
outmsg4 db "The total number of swaps is: ", 0
outmsg5 db "The sorted values are now: ", 0
outputtingVal db 0

; Uninitialized data for storing inputs
segment .bss
	n resd 1
	
	holder1 resd 1
	holder2 resd 1
	currentSpot resd 1
	nextSpot resd 1
	numOfSwaps resd 1
	inputs resd 1000		; declare array size

; Code for program to run
segment .text
	global asm_main
	
asm_main:
	enter 0,0
	pusha

; Prompt for, read and store inputs

	mov eax, prompt0 	; what is n?
	call print_string

	call read_int		; read and store n
	mov [n], eax
	
	mov ecx, [n]			; holds n for input prompt loop
	
	; ebx holds location of which value is currently being filled in
	mov ebx, inputs
	mov edx, n		; holds value being inserted for outputing

read_ints:
	mov eax, prompt1 	; Prompt for next value
	call print_string
	mov eax, [outputtingVal]
	call print_int
	mov eax, prompt3
	call print_string

	call read_int		; read and store int 
	mov ebx, eax		
	add ebx, 4			; increment location for next array spot
	mov eax, [outputtingVal]
	add eax, 1
	mov [outputtingVal], eax
	
	loop read_ints

	; prompt for sort type
	mov eax, prompt2
	call print_string
	
	call read_int
	mov edx, eax
	
	mov eax, [n]
	sub eax, 1		; n now holds right limit index
	
	; push parameters for subroutine
	push inputs
	push 0
	push eax
	
	cmp edx, 1
	je bubble_call

quick_call:
	; call quick_sort
	jmp short after_call

bubble_call:
	call bubble_sort
	
after_call:
	add ebp, 12
	
	; print number of swaps
	mov eax, outmsg4
	call print_string
	pop eax
	call print_int
	
	; print sorted list
	mov eax, outmsg5
	call print_string
	mov ecx, [n]
	mov ebx, inputs
	for_printing:
		mov eax, ebx
		call print_int
		add ebx, 4
		loop for_printing

	popa
	mov eax, 0		; return back to c
	leave
	ret
	
	
; Signed Bubble Sort Routine
; int bubble_sort (ref int * a, int left_index, int right_index)
; Parameters:
; a - pointer to begining index of array to be sorted, passed by reference
; a will be changed as a side effect of this routine

segment .text
	global bubble_sort
	extern print_f
bubble_sort:
	enter 0,0
	
	push ebx
	push ecx
	push edx
		
	mov ebx, [ebp+28]		; ebx = array begining index
	mov ecx, [ebp+20]		; ecx = right-most index
	mov edx, [ebp+24]		; edx = left-most index
	
	mov eax, 0
	
	; display that a bubble sort is being performed
	mov eax, outmsg2
	call print_string
	call print_nl
			
	while_loops:
		mov edx, 0		; swapped := false
		mov ebx, [ebp+28]	; ebx := start of array
		mov eax, [ebp+28]
		add eax, 4		; eax := next element
		mov ecx, [ebp+20]		
		sub ecx, [ebp+24]	; ecx = right-most index - left-most = loop runs
		
		for_loop:

			cmp ebx, eax	; if A[i] > A[i+1]
			jle after_if
			push edx		; swap ( A[i], A[i+1] )
			mov edx, ebx			
			mov ebx, eax
			mov eax, edx
			pop edx
			add edx, 1		; number of swaps ++
		
			after_if:
				add ebx, 4		; i++ for accessing array
				add eax, 4
				loop for_loop
				
		cmp edx, 1		; Repeat if anything was previously swapped
		
		jge while_loops
	
	mov eax, edx	; to return number of swaps
	
	pop edx
	pop ecx
	pop ebx
	push eax
	
	leave
	ret
	
; Signed Quick Sort Routine
; void quick_sort (ref int * a, int left_index, int right_index)
; Parameters:
; a - pointer to begining index of array to be sorted, passed by reference
; a will be changed as a side effect of this routine

segment .text
	global quick_sort
	extern print_f
quick_sort:
	enter 0,0
	
	push ebx
	push ecx
	push edx
	
	mov ebx, [ebp+28]		; ebx = array begining index
	mov ecx, [ebp+20]		; ecx = right-most index
	mov edx, [ebp+24]		; edx = left-most index
	
	mov eax, edx		; check is length(array) <= 1
	sub eax, ecx
	cmp eax, 1
	jle done
	
	mov eax, ebx		; eax = pivot
	add eax, edx
	
	add ebx, ecx		; ebx = first in array portion
	
	for_pivoting:
		cmp ebx, eax
		jle less
		
		greater:
			; append to greater
		less:
			; append to less
	
	; quicksort less, quicksort greater and combine them to one list
	
	done:
		pop edx
		pop ecx
		pop ebx
		push eax
		
		leave
		ret
	